package com.ruoyi.common.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.ruoyi.framework.config.AliyunOssConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 阿里云存储
 * https://blog.52itstyle.vip
 */
@Component
@Slf4j
public class AliyunOssUtil {

    private static final long IMAGE_EXPIRE_TIME = 10 * 365 * 24 * 60 * 60 * 1000L;//图片访问链接的过期时间

    private static OSS ossClient;

    /**
     * 初始化
     */
    public static void init() {
        ossClient = new OSSClientBuilder().build(AliyunOssConfig.ENDPOINT, AliyunOssConfig.ACCESS_KEY_ID, AliyunOssConfig.ACCESS_KEY_SECRET);
    }

    /**
     * 销毁
     */
    public static void destory() {
        ossClient.shutdown();
    }

    /**
     * 删除单个文件
     * @param imgUrl
     * @return
     */
    public void deleteImage(String imgUrl){
        try{
            init();
            ossClient.deleteObject(AliyunOssConfig.BUCKET_NAME,imgUrl);
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            destory();
        }
    }

    /**
     * 删除多个文件
     * @param imgUrls
     * @return
     */
    public List<String> deleteMoreImage(String imgUrls){
        try{
            init();
            // 删除文件。key等同于ObjectName，表示删除OSS文件时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
            List<String> keys = new ArrayList<>();
            String[] imgArr = imgUrls.split(",");
            for (int i=0; i<imgArr.length;i++) {
                keys.add(imgArr[i]);
            }
            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(AliyunOssConfig.BUCKET_NAME).withKeys(keys));
            //删除结果。详细模式下为删除成功的文件列表，简单模式下为删除失败的文件列表。
            return deleteObjectsResult.getDeletedObjects();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            destory();
        }
        return null;
    }


    /**
     * @param: instream
     * @param: fileName
     * @Return: java.lang.String
     * @Decription: 上传图片至OSS
     * @CreateDate: Created in 2018/12/11 16:36
     * @Modify:
     */
    public String uploadImageToOSS(MultipartFile file, String fileName) {
//        if (ossClient == null) {
            init();
//        }
        String ret = "";
        try {
            //创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(file.getInputStream().available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getcontentType(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);
            //上传文件
            PutObjectResult putResult = ossClient.putObject(AliyunOssConfig.BUCKET_NAME, fileName, file.getInputStream(), objectMetadata);
            ret = putResult.getETag();
        } catch (IOException e) {
            log.error("upload file to oss error name={}", fileName, e);
        } finally {
            try {
                destory();
                if (file.getInputStream() != null) {
                    file.getInputStream().close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * @param: FilenameExtension
     * @Return: java.lang.String
     * @Decription: 判断OSS服务文件上传时文件的contentType
     * @CreateDate: Created in 2018/12/11 17:19
     * @Modify:
     */
    public static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpeg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpeg";
    }

    /**
     * @param: fileName
     * @param type 自定义图片存放归类，比如机构图片为org
     * @Return: java.lang.String
     * @Decription: 根据图片名称获取图片访问地址
     * @CreateDate: Created in 2018/12/11 17:18
     * @Modify:
     */
    public String getImageUrl(String fileName,String type) {
        // 设置URL过期时间
        Date expiration = new Date(new Date().getTime() + IMAGE_EXPIRE_TIME);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(AliyunOssConfig.BUCKET_NAME, type+"/" + fileName, expiration);
        if (url != null) {
            return url.toString();
        }
        return null;
    }

    public void selectJsonSample(String key) {
        try {
            if (ossClient == null) {
                init();
            }
            final String content = "{\n" +
                    "\t\"name\": \"Lora Francis\",\n" +
                    "\t\"age\": 27,\n" +
                    "\t\"company\": \"Staples Inc\"\n" +
                    "}\n" +
                    "{\n" +
                    "\t\"name\": \"Eleanor Little\",\n" +
                    "\t\"age\": 43,\n" +
                    "\t\"company\": \"Conectiv, Inc\"\n" +
                    "}\n" +
                    "{\n" +
                    "\t\"name\": \"Rosie Hughes\",\n" +
                    "\t\"age\": 44,\n" +
                    "\t\"company\": \"Western Gas Resources Inc\"\n" +
                    "}\n" +
                    "{\n" +
                    "\t\"name\": \"Lawrence Ross\",\n" +
                    "\t\"age\": 24,\n" +
                    "\t\"company\": \"MetLife Inc.\"\n" +
                    "}";

            ossClient.putObject(AliyunOssConfig.BUCKET_NAME, key, new ByteArrayInputStream(content.getBytes()));

            SelectObjectRequest selectObjectRequest =
                    new SelectObjectRequest(AliyunOssConfig.BUCKET_NAME, key)
                            .withInputSerialization(new InputSerialization()
                                    .withCompressionType(CompressionType.NONE)
                                    .withJsonInputFormat(new JsonFormat().withJsonType(JsonType.LINES)))
                            .withOutputSerialization(new OutputSerialization()
                                    .withCrcEnabled(true)
                                    .withJsonOutputFormat(new JsonFormat()))
                            .withExpression("select * from ossobject as s where s.age > 40");

            OSSObject ossObject = ossClient.selectObject(selectObjectRequest);

            // read object content from ossObject
            BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
            while (true) {
                String line = reader.readLine();
                if (line == null) {
                    break;
                }
                System.out.println(line);
            }
            reader.close();
        }catch (Exception e){

        }finally {
            ossClient.deleteObject(AliyunOssConfig.BUCKET_NAME, key);
        }


    }

}
